import * as step from '@flow-step/step-toolkit'
import * as sinon from 'sinon'
import {expect} from 'chai'
import process from 'process'
import {getJenkinsCertificate} from '../src/certificate'

type JenkinsCertificate = {
    jenkinsMaster: string
    jenkinsUsername: string
    jenkinsPassword: string
}

describe('Jenkins Certificate Function', () => {
    let sandbox: sinon.SinonSandbox
    let processEnv: NodeJS.ProcessEnv
    let getJenkinsCertificateStub: any

    before(() => {
        sandbox = sinon.createSandbox()
        processEnv = process.env

        getJenkinsCertificateStub = sandbox.stub(step.certificate, 'getJenkinsCertificate')
    })

    after(() => {
        sandbox.restore()
        process.env = processEnv
    })

    it('should handle "serviceConnection" authType correctly', async () => {
        process.env.SERVICE_CONNECTION_ID = 'mockJenkinsConnectionId'
        process.env.FLOW_JOB_TOKEN = 'mockFlowJobToken'

        const mockCertificate: JenkinsCertificate = {
            jenkinsMaster: 'http://jenkins.example.com',
            jenkinsUsername: 'mockUsername',
            jenkinsPassword: 'mockPassword'
        }
        getJenkinsCertificateStub.resolves(mockCertificate)

        const certificate = await getJenkinsCertificate()
        sinon.assert.calledWith(getJenkinsCertificateStub, 'mockFlowJobToken', 'mockJenkinsConnectionId')
        expect(certificate).to.deep.equal(mockCertificate)
    })

    it('should throw error when SERVICE_CONNECTION_ID is missing', async () => {
        delete process.env.SERVICE_CONNECTION_ID
        process.env.FLOW_JOB_TOKEN = 'mockFlowJobToken'

        try {
            await getJenkinsCertificate()
            expect.fail('Expected an error to be thrown')
        } catch (error) {
            // @ts-ignore
            expect(error.message).to.equal('missing SERVICE_CONNECTION_ID')
        }
    })

    it('should throw error when FLOW_JOB_TOKEN is missing', async () => {
        process.env.SERVICE_CONNECTION_ID = 'mockJenkinsConnectionId'
        delete process.env.FLOW_JOB_TOKEN
        try {
            await getJenkinsCertificate()
            expect.fail('Expected an error to be thrown')
        } catch (error) {
            // @ts-ignore
            expect(error.message).to.equal('missing FLOW_JOB_TOKEN')
        }
    })

    it('should throw error when getJenkinsCertificate returns invalid data', async () => {
        process.env.SERVICE_CONNECTION_ID = 'mockJenkinsConnectionId'
        process.env.FLOW_JOB_TOKEN = 'mockFlowJobToken'

        const mockCertificate: JenkinsCertificate = {
            jenkinsMaster: '',
            jenkinsUsername: 'mockUsername',
            jenkinsPassword: 'mockPassword'
        }
        getJenkinsCertificateStub.resolves(mockCertificate)

        try {
            await getJenkinsCertificate()
            expect.fail('Expected an error to be thrown')
        } catch (error) {
            // @ts-ignore
            expect(error.message).to.include('get JenkinsCertificate but error:')
        }
    })
})
